/*
 * FileName: csharedptr.cc
 * Author: 李波(Edwin Lee)
 * Date: 2024-07-05 19:43:31
 * Version: 1.0
 * Description:带计数器的智能指针 
 */
#include <iostream>
using namespace std;

//对资源进行引用计数的类
template <typename T>
class RefCnt
{
public:
	RefCnt(T* ptr = nullptr)
		:mptr(ptr)
	{
		if(mptr != nullptr)
			mcount = 1;
	}

	void addRef(){++mcount;}

	int delRef(){return --mcount;}
	


private:
	T* mptr;
	int mcount;
};

template <typename T>
class CSmartPtr
{
public:
	CSmartPtr(T* ptr = nullptr)
		:mptr(ptr)
	{
		mpRefCnt = new RefCnt<T>(mptr);
	}

	CSmartPtr(const CSmartPtr<T>& src)
		:mptr(src.mptr)
		,mpRefCnt(src.mpRefCnt)
	{
		if(mptr != nullptr)
			mpRefCnt->addRef();
	}

	~CSmartPtr()
	{
		if(0 == mpRefCnt->delRef())
		{
			delete mptr;
			mptr = nullptr;
		}
	}

	T& operator*()
	{
		return *mptr;
	}

	T* operator->()
	{
		return mptr;
	}

	CSmartPtr<T>& operator=(const CSmartPtr<T>& src)
	{
		if(this == &src)
			return *this;
		if(0 == mpRefCnt->delRef())
		{
			delete mptr;
		}
		mptr = src.mptr;
		mpRefCnt = src.mpRefCnt;
		mpRefCnt->addRef();
		return *this;
	}

private:
	T* mptr;
	RefCnt<T>* mpRefCnt;
};

class Test 
{
public:
	void echo()
	{
		cout<<"call Test::echo"<<endl;
	}
};
int main()
{
	CSmartPtr<int> intptr1(new int);
	CSmartPtr<int> intptr2(intptr1);
	CSmartPtr<int> intptr3;
	intptr3 = intptr2;

	*intptr1 = 100;
	cout<<*intptr2<<" "<<*intptr3<<endl;
	return 0;
}
